using Godot;
using System;

namespace CurrentGame.GUI;


public partial class PauseMenu : Control
{
	[Signal]
	public delegate void GamePauseStateChangedEventHandler(bool paused);

	[Export]
	public bool EnablePauseMenu { get; set; } = false;

	[Export]
	public bool CaptureMouse { get; set; } = false;


	private bool _paused = false;
	private Player _player;
	private SceneTree _sceneTree;
	private GameProgressManager _progressManager;

	// Child node reference
	private Button _resumeButton, _exitButton;


	// Called when the node enters the scene tree for the first time.
	public override void _Ready()
	{
		var map = GetNode<NodeReferenceMap>(Constants.NodeRefMapPath);
		_player = map.MainPlayer;
		_progressManager = map.ProgressManager;
		_sceneTree = GetTree();

		_resumeButton = GetNode<Button>("VBoxContainer/Continue");
		_exitButton = GetNode<Button>("VBoxContainer/Exit");
	}

	// Called every frame. 'delta' is the elapsed time since the previous frame.
	public override void _Process(double delta)
	{
		if (EnablePauseMenu && Input.IsActionJustPressed("pause_game"))
		{
			if (_paused) ResumeGame();
			else PauseGame();
		}
	}

	private void ResumeGame()
	{
		Visible = false;
		_resumeButton.Disabled = true;
		_exitButton.Disabled = true;

		_paused = false;
        _sceneTree.Paused = false;
        _player.EnableInputCheck();

		if (CaptureMouse)
			Input.MouseMode = Input.MouseModeEnum.Captured;
		EmitSignal(SignalName.GamePauseStateChanged, _paused);
	}

	private void PauseGame()
	{
		Visible = true;
		_resumeButton.Disabled = false;
		_exitButton.Disabled = false;

		_paused = true;
		_sceneTree.Paused = true;
		_player.SkipInputCheck();

		_resumeButton.CallDeferred(MethodName.GrabFocus);

		Input.MouseMode = Input.MouseModeEnum.Visible;
		EmitSignal(SignalName.GamePauseStateChanged, _paused);
	}


	// GODOT Signals
	private void Signal_ResumeClicked()
	{
		ResumeGame();
	}

	private void Signal_ExitClicked()
	{
		_sceneTree.Quit();
	}

	private void Signal_RestartClicked()
	{
		ResumeGame();
		if (_progressManager.ExtremeMode) _player.StartTargetLevel("start_level");
		else _player.RestartThisLevel();
	}
}
